01 demo.hsp

sample\ 01 demo.hsp

; ちょっとリッチなアニメーション付きボタンを比較的簡単に作成できます。

#include "hsp3dish.as"

#include "mod_layerbutton.hsp"
#include "d3m.hsp"  ; FPS計測用

#packopt xsize 480
#packopt ysize 800

	screen 0,480,800
	title "layerbutton demo"
	log = ""
	// HSP3Dish.js用フォルダ設定
	info_os = sysinfo(0)
	if instr(info_os,0,"Emscripten")>=0 : mm_dir="" : else : mm_dir="data/"
	
	// 画像読み込み
	celload mm_dir+"03_01-btn.png", -1
	cel_btn = stat
	celdiv cel_btn,172,66
	celload mm_dir+"icon.png", -1
	cel_ico = stat
	celdiv cel_ico,32,32, 16,16
	
	// オブジェクト作成
	gosub *create_button_hidari
	gosub *create_button_migi
	gosub *create_button_shita

	// 表示ループ
	repeat
		redraw 0 :color 240,240,240 : boxf : color : pos 0,0 : font msgothic,14
		mes "fps = " + d3getfps()
		mes log
		if laybtn_length(0) == 0 && laybtn_length(1) == 0 {
			pos 50,650 : mes "グループが1つの場合、移動キーでフォーカスが発生します。\n(オプションで発生させないことも可能)"
		}
		redraw 1
		await 16
	loop
	stop

// 左側ボタン作成
*create_button_hidari
	if laybtn_length(0) > 0 : return  ; グループID 0 がすでに存在する場合はreturn
	pos 30,20
	repeat 4
		pos ,ginfo_cy+40  ; ボタンの位置を調整
		tien = cnt * 10  ; IDごとに表示遅延をつける(SHOW_IN:10フレーム、SHOW_OUT:5フレーム)
		// ボタン作成 : グループID 0
		layerbutton 172,66, cnt, 0, 30+tien,20,10, 15+tien/2,10,0 {
			if lparam == objlayer_cmddraw {
				mes_zurasi = 0,-5  ; テキスト表示の基準位置
				tien = objlayer_option * 10  ; optionに代入したボタンIDに合わせて遅延時間を計算
				// ボタンの状態に応じて描画を振り分ける
				switch layerbtn_stat
				case LAYBTN_SHOW_IN // 表示開始
					pos objlayer_axis_x-laybtn_ease(200, 0, tien), objlayer_axis_y  ; 左からスライドイン(ボタンIDごとの遅延時間を考慮)
					gmode 3,,,255 : celput cel_btn, 0  ; ボタン描画
					mes_zurasi = -laybtn_ease(200, 0, tien),-5  ; スライドインに合わせてテキスト位置もスライド
					swbreak
				case LAYBTN_FOCUS_IN // フォーカス表示
					pos objlayer_axis_x, objlayer_axis_y
					gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
					pos objlayer_axis_x, objlayer_axis_y
					gmode 3,,,laybtn_ease(0,256) : celput cel_btn, 1  ; ボタン描画 : フォーカス状態(透明度をイージングで徐々に変化)
					swbreak
				case LAYBTN_FOCUS_OUT // フォーカス解除
					pos objlayer_axis_x, objlayer_axis_y
					gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
					pos objlayer_axis_x, objlayer_axis_y
					gmode 3,,,laybtn_ease(256,0) : celput cel_btn, 1  ; ボタン描画 : フォーカス状態(透明度をイージングで徐々に変化)
					swbreak
				case LAYBTN_PRESS_IN // 押し込み表示
					pos objlayer_axis_x, objlayer_axis_y
					gmode 3,,,256 : celput cel_btn, 2  ; ボタン描画 : 押し込み状態(アニメーションなしで瞬時に表示にした)
					mes_zurasi = 0,-1  ; ボタン押し込みに合わせてテキスト位置を下げる(-5 → -1)
					swbreak
				case LAYBTN_SHOW_OUT // 非表示処理
				case LAYBTN_SHOW_OUT_SELECTED
					if layerbtn_stat == LAYBTN_SHOW_OUT_SELECTED && layerbtn_cnt == 0 {
						// ボタンが選択された瞬間!!
						log += "hidari - SELECTED! opt="+objlayer_option+" wparam="+wparam +"\n"
					}
					pos objlayer_axis_x-laybtn_ease(0, 200, tien/2), objlayer_axis_y  ; 左へスライドアウト(ボタンIDごとの遅延時間を考慮)
					if layerbtn_stat & LAYBTN_SELECTED {  ; 選択されたボタンのスライドアウト表示
						gmode 3,,,256 : celput cel_btn, 2  ; ボタン描画 : 押し込み状態
						mes_zurasi = -laybtn_ease(0, 200, tien/2),-1  ; スライドインに合わせてテキスト位置もスライド + 押し込みテキスト位置
					} else {                              ; 選択されていないボタンのスライドアウト表示
						gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
						mes_zurasi = -laybtn_ease(0, 200, tien/2),-5  ; スライドインに合わせてテキスト位置もスライド
					}
					swbreak
				case LAYBTN_COMPLETE
				case LAYBTN_COMPLETE_SELECTED
					if layerbtn_stat & LAYBTN_SELECTED {
						// グループ内のすべてのボタンの非表示処理が完了したとき (選択されたボタンはLAYBTN_COMPLETE_SELECTEDで通知される)
						log += "hidari - COMPLETE! opt="+objlayer_option+" wparam="+wparam +"\n"
					}
					return
					swbreak
				swend
				color 0,0,0 : objcolor 255,255,255 : font msgothic, 18, 1  ; laybtn_ezboxのテキスト設定
				laybtn_mes "ボタン0"+(objlayer_option+1),4, 1,1, mes_zurasi(0),mes_zurasi(1)  ; テキスト描画

				// ボタンの無効表示
				laybtn_enable 0, -1
				if stat == 0  {
					gmode 3,,,100 : color 
					boxfao objlayer_axis_x, objlayer_axis_y-20, objlayer_axis_x2, objlayer_axis_y2+20
					if objlayer_option == 3 : color 0,0,0 : font msgothic, 14 : laybtn_mes "無効 : 適当に黒半透明を被せてます\n(好みの表示にして下さい)",0, 1,2, 10,52
				}
			}
			return
		}
	loop
	return

// 右側ボタン作成
*create_button_migi
	if laybtn_length(1) >= 3 : return  ; グループID 1 がすでに存在する場合はreturn
	repeat 4
		switch cnt
		case 0 : pos 220, 150 : swbreak
		case 1 : pos 350, 150 : swbreak
		case 2 : pos 220, 260 : swbreak
		case 3 : pos 350, 260 : swbreak
		swend
		// ボタン作成 : グループID 1
		layerbutton 120,100, cnt, 1, 30,20,5, 15,20,2 {
			laybtn_settings 0,0,16  ; 設定変更 :  FOCUS_IN の表示が完了する前にフォーカスが外れたとき FOCUS_OUT を即座に開始させる。  
			if lparam == objlayer_cmddraw {
				// ボタンの描画
				color 255,255,255 : objcolor 0,0,0 : font msgothic, 18, 1  ; laybtn_ezboxのテキスト設定
				laybtn_ezbox $AA9999FF, $AA0000FF, $AA3333AA, "ボックス0"+(objlayer_option+1)
				// ボタンのクリック判定
				switch layerbtn_stat
				case LAYBTN_SHOW_OUT_SELECTED
					if layerbtn_cnt == 0 : log += "migi - SELECTED! opt="+objlayer_option+" wp="+wparam +"\n"
					swbreak
				case LAYBTN_COMPLETE_SELECTED
					log += "migi - COMPLETE! opt="+objlayer_option+" wp="+wparam +"\n"
					swbreak
				swend

				// ボタンの無効表示
				laybtn_enable 1, -1
				if stat == 0  {
					gmode 3,,,100 : color 
					boxfao objlayer_axis_x-5, objlayer_axis_y-5, objlayer_axis_x2+5, objlayer_axis_y2+5
					if objlayer_option == 3 : color 0,0,0 : font msgothic, 14 : laybtn_mes "無効 : 適当に黒半透明を被せてます\n(好みの表示にして下さい)",0, 2,2, -10,40
				}
			}
			return
		}
	loop
	return

// 下側ボタン作成
*create_button_shita
	repeat 7
		pos 65+50*cnt, 500
		// ボタン作成 : グループID 2
		layerbutton 50,50, cnt, 2, 0,15,20, 0,0,0 {
			laybtn_settings 0,2,1+2+8  ; 設定変更 : 押しても消えない+PRESSアニメ待ち+マウスクリック即ボタン決定
			if lparam == objlayer_cmddraw {
				// ボタンの描画
				color 255,255,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2  ; ボタン下地描画
				pos objlayer_axis_x+25, objlayer_axis_y+25  ; アイコンの基準位置をpos
				switch layerbtn_stat
				case LAYBTN_FOCUS_IN // フォーカスと押し込み両方で虹色カーソル描画をするのでまとめる
				case LAYBTN_PRESS_IN
				case LAYBTN_PRESS_IN_SELECTED
					// グラデーション四角カーソルの描画
					if layerbtn_stat & LAYBTN_FOCUS_IN  : fade = 0,255   ; フェードイン
					if layerbtn_stat & LAYBTN_PRESS_IN  : fade = 255,255 ; ボタンクリック
					grdc++  ; グラデーションカラーをくるくるさせるためにカウント(HSV形式 H値:0~191)
					hsvcolor (grdc \ 192), laybtn_ease(fade.0, fade.1), 255  ; グラデーションパラメータ
					x(0)=objlayer_axis_x +2 : y(0)=objlayer_axis_y +2 : col(0)=ginfo_r<<16|ginfo_g<<8|ginfo_b
					hsvcolor (grdc+48 \ 192), laybtn_ease(fade.0, fade.1), 255
					x(1)=objlayer_axis_x2-2 : y(1)=objlayer_axis_y +2 : col(1)=ginfo_r<<16|ginfo_g<<8|ginfo_b
					hsvcolor (grdc+96 \ 192), laybtn_ease(fade.0, fade.1), 255
					x(2)=objlayer_axis_x2-2 : y(2)=objlayer_axis_y2-2 : col(2)=ginfo_r<<16|ginfo_g<<8|ginfo_b
					hsvcolor (grdc+144 \ 192), laybtn_ease(fade.0, fade.1), 255
					x(3)=objlayer_axis_x +2 : y(3)=objlayer_axis_y2-2 : col(3)=ginfo_r<<16|ginfo_g<<8|ginfo_b
					gmode 0,,,256 : gsquare -257, x,y,col  ; カーソル描画
					color 255,255,255 : boxf objlayer_axis_x+4, objlayer_axis_y+4, objlayer_axis_x2-5, objlayer_axis_y2-5  ; 中抜きして枠にする
					// アイコンが跳ねたような描画位置になるよう調整 (一度_PRESS_INに入ったら_IN→_OUTが終わるまでカウントされる)
					if layerbtn_stat & LAYBTN_PRESS_IN {
						if layerbtn_cnt <= 5 {
							pos objlayer_axis_x+25, objlayer_axis_y+25-laybtn_ease(0, 13)  ; 5フレーム上にあげる
						}else {
							pos objlayer_axis_x+25, objlayer_axis_y+25-laybtn_ease(13, 0, 5, ease_bounce_out)  ; 残りのフレームをバウンド落下
						}
					}
					swbreak
				swend
				// アイコン描画
				gmode 3,,,256 : celput cel_ico, objlayer_option
				// テキスト描画
				if (layerbtn_stat & LAYBTN_FOCUS_IN)!=0 || (layerbtn_stat & LAYBTN_PRESS_IN)!=0 {
					color 0,0,200 : font msgothic, 14  ; laybtn_ezboxのテキスト設定
					switch objlayer_option
					case 0 : laybtn_mes "左ボタン表示/非表示",0, 1,1, 0,40 : swbreak
					case 2 : laybtn_mes "左ボタン有効/無効",0, 1,1, 0,40 : swbreak
					case 3 : laybtn_mes "右ボタン表示/非表示",0, 1,1, 0,40 : swbreak
					case 5 : laybtn_mes "右ボタン有効/無効",0, 1,1, 0,40 : swbreak
					case 6 : laybtn_mes "終了",0, 1,1, 0,40 : swbreak
					default : 
						laybtn_mes "1つ目のボタンにフォーカス",0, 1,1, 0,40
						laybtn_mes "(キー入力でもフォーカス移動と決定が可能)",0, 1,1, 0,54
						swbreak
					swend
				}

				// ボタンのクリック判定 (設定:マウスクリック即ボタン決定)
				if layerbtn_stat == LAYBTN_PRESS_IN_SELECTED {
					log += "shita - SELECTED! opt="+objlayer_option+" wparam="+wparam +"\n"
					switch objlayer_option
					case 0 : if laybtn_length(0) != 0 { laybtn_hide 0 }else{ gosub *create_button_hidari } : swbreak
					case 1 : laybtn_focus 0, 0 : swbreak
					case 2 : laybtn_enable 0, -1 : laybtn_enable 0, 1 - stat : swbreak
					case 3 : if laybtn_length(1) != 0 { laybtn_hide 1 }else{ gosub *create_button_migi } : swbreak
					case 4 : laybtn_focus 1, 0 : swbreak
					case 5 : laybtn_enable 1, -1 : laybtn_enable 1, 1 - stat : swbreak
					case 6 : flg_end = 1 : swbreak
					swend
				}
				if flg_end == 1 && layerbtn_stat == LAYBTN_PRESS_IN && layerbtn_cnt == 19 : dialog "終了します" : end
			}
			return
		}
	loop
	return

#module
#deffunc boxfao int ax, int ay, int bx, int by, int ox, int oy
	pdx=ax+ox,bx+ox,bx+ox,ax+ox
	pdy=ay+oy,ay+oy,by+oy,by+oy
	gsquare -1,pdx,pdy
	return
#global